package action;

import i18n.Internacionalization;

import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import net.roarsoftware.lastfm.Album;
import net.roarsoftware.lastfm.Artist;
import net.roarsoftware.lastfm.Playlist;
import net.roarsoftware.lastfm.Result;
import net.roarsoftware.lastfm.Session;
import net.roarsoftware.lastfm.Track;
import net.roarsoftware.lastfm.User;

import service.PlayListService;
import service.UserInformationService;
import service.impl.PlayListServiceImpl;
import service.impl.UserInformationServiceImpl;
import util.SearchCommandsLastfm;
import view.RenderView;

import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.FormView;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;
import com.google.wave.api.Event;
import com.google.wave.api.EventType;
import com.google.wave.api.RobotMessageBundle;
import com.sun.org.apache.bcel.internal.generic.CPInstruction;

import common.Constants;
import common.Operation;

@SuppressWarnings("serial")
public class LastfmRobotWaveServlet extends AbstractRobotServlet {
	
	private PlayListService playListService = PlayListServiceImpl.getInstance();
	private UserInformationService userInformationService = UserInformationServiceImpl.getInstance();
	private SearchCommandsLastfm searchCommands = SearchCommandsLastfm.getInstance();
	
	private Playlist playlist;
	private Session session;

	@Override
	public void processEvents(RobotMessageBundle bundle) {
		Wavelet wavelet = bundle.getWavelet();

		if (bundle.wasSelfAdded()) {
			Blip blip = wavelet.appendBlip();
			TextView textView = blip.getDocument();
			textView.append("Soy el robot LastfmWave, te ayudaré a interaccionar con last.fm desde Google Wave.");
			textView.append("\nUtiliza los siguientes comandos:");
			textView.append("\n@lw.neighbours:user (Muestra la lista de vecinos del usuario 'user')");
			textView.append("\n@lw.recent-tracks:user (Muestra las canciones escuchadas recientemente por 'user')");
			textView.append("\n@lw.top-albums:user (Muestra los Top Albums del usuario 'user')");
			textView.append("\n@lw.top-artist:user (Muestra los Top Artist del usuario 'user')");
			textView.append("\n@lw.create-playlist (Muestra el formulario necesario para la creación de un playlist, requiere login)");
			textView.append("\n@lw.add-track (Muestra el formulario necesario para añadir canciones al playlist, requiere un playlist creado)");
			textView.append("\n@lw.show-playlist (Muestra el playlist que se está creando, requiere un playlist creado)");
		}
		for (Event e : bundle.getEvents()) {
			if (e.getType() == EventType.BLIP_SUBMITTED) {
				TextView content = e.getBlip().getDocument();
				String blipText = content.getText();
				List<String> commands = searchCommands.findCommandsInText(blipText);
				if (commands.size() > 0) {
					List<Operation> operations = searchCommands.getOperationsFromCommands(commands);
					for (Operation operation : operations) {
						execute(operation, wavelet);
					}
				}
			}
			if(e.getType() == EventType.FORM_BUTTON_CLICKED) {
				processForm(e, wavelet);
			}
		}
	}
	
	private void execute(Operation operation, Wavelet wavelet) {
		if (operation.getType() == Constants.TYPE_OF_OPERATION.GET_NEIGHBOURS) {
			String user = operation.getParam(Operation.USER_PARAM);
			Collection<User> users =  userInformationService
				.getNeighbours(user);
			RenderView.renderNeighboursView(wavelet, users, user);
		} else if (operation.getType() == Constants.TYPE_OF_OPERATION.GET_RECENT_TRACKS) {
			String user = operation.getParam(Operation.USER_PARAM);
			Collection<Track> tracks = userInformationService
				.getRecentTracks(user);
			RenderView.renderRecentTracksView(wavelet, tracks, user);
		} else if (operation.getType() == Constants.TYPE_OF_OPERATION.GET_TOP_ALBUMS) {
			String user = operation.getParam(Operation.USER_PARAM);
			Collection<Album> albums = userInformationService
				.getTopAlbums(user);
			RenderView.renderTopAlbumsView(wavelet, albums, user);
		} else if (operation.getType() == Constants.TYPE_OF_OPERATION.GET_TOP_ARTIST) {
			String user = operation.getParam(Operation.USER_PARAM);
			Collection<Artist> artists = userInformationService
				.getTopArtists(user);
			RenderView.renderTopArtistView(wavelet, artists, user);
		} else if (operation.getType() == Constants.TYPE_OF_OPERATION.CREATE_PLAYLIST) {
			if (session != null) {
				RenderView.renderCreatePlayistView(wavelet);
			} else {
				RenderView.renderLoginView(wavelet);
			}
		} else if (operation.getType() == Constants.TYPE_OF_OPERATION.ADD_TRACK) {
			if (playlist != null) {
				RenderView.renderAddTrackView(wavelet);
			} else {
				RenderView.renderCreatePlayistView(wavelet);
			}
		} else if (operation.getType() == Constants.TYPE_OF_OPERATION.GET_PLAYLIST) {
			if (playlist != null) {
				Playlist playlist = playListService.getPlaylist(this.playlist.getId());
				RenderView.renderShowPlaylistView(wavelet, playlist); 
			} else {
				Blip blip = wavelet.appendBlip();
				TextView textView = blip.getDocument();
				textView.append(Internacionalization.getString("No se ha creado ningún playlist"));
			}
		}
	}
	
	private void processForm(Event e, Wavelet wavelet) {
		FormView formView = e.getBlip().getDocument().getFormView();
		if(formView.getFormElement(RenderView.ID_BUTTON_LOGIN) != null) {			
			String user = formView.getFormElement(RenderView.ID_INPUT_USER).getValue();
			String pass = formView.getFormElement(RenderView.ID_INPUT_PASS).getValue();
			session = playListService.createSession(user, pass);
			if (session != null) {
				e.getBlip().getDocument().delete();
				TextView textView = e.getBlip().getDocument();
				textView.append("\nUsuario conectado correctamente");
				RenderView.renderCreatePlayistView(wavelet);
			} else {
				TextView textView = e.getBlip().getDocument();
				textView.append("\nUsuario o contraseña incorrectos, vuelva a intentarlo.");
			}
		} else if(formView.getFormElement(RenderView.ID_BUTTON_CREATE_PLAYLIST) != null) {
			String name = formView.getFormElement(RenderView.ID_INPUT_NAME).getValue();
			String description = formView.getFormElement(RenderView.ID_INPUT_DESCRIPTION).getValue();
			playlist = playListService.create(name, description, session);
			if (playlist != null) {
				e.getBlip().getDocument().delete();
				TextView textView = e.getBlip().getDocument();
				textView.append("Playlist creado correctamente");
			} else {
				TextView textView = e.getBlip().getDocument();
				textView.append("Se produjo un error al crear el playlist");
			}
		} else if(formView.getFormElement(RenderView.ID_BUTTON_ADD_TRACK) != null) {
			String track = formView.getFormElement(RenderView.ID_INPUT_TRACK).getValue();
			String artist = formView.getFormElement(RenderView.ID_INPUT_ARTIST).getValue();
			Result result = playListService.addTrack(artist, track, session, playlist.getId());
			if (result.isSuccessful()) {
				e.getBlip().getDocument().delete();
				TextView textView = e.getBlip().getDocument();
				textView.append("Canción añadida correctamente");
			} else {
				e.getBlip().getDocument().delete();
				TextView textView = e.getBlip().getDocument();
				textView.append("Error al añadir la canción a la lista");
			}
		}
	}
}
